package fun.codedesign.jdk.socket.nio;


import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Set;

/**
 * @author zengjian
 * @create 2018-04-17 10:36
 * @since 1.0.0
 */
public class NioClient {

    private Selector selector;
    private SocketChannel socketChannel;

    public NioClient() {
        try {
            selector = Selector.open();
            socketChannel = SocketChannel.open(new InetSocketAddress(8080));
            // 如果为true就不能注册到多路复用器上
            socketChannel.configureBlocking(false);
            socketChannel.register(selector, SelectionKey.OP_CONNECT);
            socketChannel.register(selector, SelectionKey.OP_READ);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String sendMessage(String message) throws IOException {
        ByteBuffer byteBuffer = ByteBuffer.allocate(message.getBytes().length);
        byteBuffer.put(message.getBytes("utf-8"));
        byteBuffer.flip();
        socketChannel.write(byteBuffer);

        while (true) {
            int count = selector.select(); // 关键步骤，需要在这里轮询，否则下放的selectionKeys无法得到
            if (count == 0) {
                continue;
            }
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            for (SelectionKey selectionKey : selectionKeys) {
                if (selectionKey.isConnectable()) {
                    System.out.println(selectionKey + "连接上了");
                }
                if (selectionKey.isReadable()) {
                    System.out.println(selectionKey + "可读");
                    SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                    ByteBuffer dst = ByteBuffer.allocate(1024);
                    socketChannel.read(dst);
                    dst.flip();
                    byte[] bytes = new byte[dst.remaining()];
                    dst.get(bytes);
                    return new String(bytes, "utf-8");
                }
            }
            boolean timeout = false;
            if (timeout) {
                return "空";
            }
        }
    }

    public static void main(String[] args) {
        NioClient client = new NioClient();
        for (int i = 0; i < 10000; i++) {
            try {
                String resp = client.sendMessage("客户端请求" + i);
                System.out.println("请求" + i + "回复:" + resp);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
